package com.mjk.common.tools.encrypt;


import com.mjk.common.tools.logger.BizLogger;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

public class AESUtil {
	public static final String INIT_VECTOR = "aescbcinitvector";
	public static final Random random = new Random();

	private static final String CLIENT_KEY = "AES/CBC/PKCS5Padding";
	public static String encrypt(String content, String apiKey) {
		if (apiKey == null) {
			throw new IllegalArgumentException("Key cannot be null!");
		}
		if ((apiKey.length() != 32) && (apiKey.length() != 24)
				&& (apiKey.length() != 16)) {
            throw new IllegalArgumentException(
                    "Key length must be 128/192/256 bits!");
        }
		try {
			byte[] keyBytes = apiKey.getBytes();
			SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "AES");
			IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes());
			Cipher cipher = Cipher.getInstance(CLIENT_KEY);

			cipher.init(1, skeySpec, iv);
			byte[] encrypted = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
			return parseByte2HexStr(encrypted);
		} catch (Exception e) {
			BizLogger.error(e);
		}
		return "";
	}

	public static String decrypt(String content, String apiKey)
			throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		if ((apiKey == null) || (content == null)) {
			throw new IllegalArgumentException("Key cannot be null!");
		}
		byte[] encryptedContent = parseHexStr2Byte(content);
		byte[] keyBytes = apiKey.getBytes();

		SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "AES");
		IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes());
		Cipher cipher = Cipher.getInstance(CLIENT_KEY);
		cipher.init(2, skeySpec, iv);

		byte[] original = cipher.doFinal(encryptedContent);

		return new String(original, StandardCharsets.UTF_8);
	}

	public static String parseByte2HexStr(byte[] buf) {
		StringBuilder sb = new StringBuilder();
        for (byte b : buf) {
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
		return sb.toString();
	}

	public static byte[] parseHexStr2Byte(String hexStr) {
		if (hexStr.isEmpty()) {
            return new byte[0];
        }
		byte[] result = new byte[hexStr.length() / 2];
		for (int i = 0; i < hexStr.length() / 2; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
					16);
			result[i] = ((byte) (high * 16 + low));
		}
		return result;
	}
	// 生成随机的IV
	public static byte[] generateIV() {
		SecureRandom random = new SecureRandom();
		byte[] iv = new byte[12];
		random.nextBytes(iv);
		return iv;
	}

}